package cn.ltgodm.template.web.controller.user;

import cn.hutool.core.util.ObjectUtil;
import cn.ltgodm.template.common.annotation.Log;
import cn.ltgodm.template.common.domain.AjaxResult;
import cn.ltgodm.template.common.domain.vo.RoleVO;
import cn.ltgodm.template.common.domain.vo.UserVO;
import cn.ltgodm.template.common.enums.BusinessType;
import cn.ltgodm.template.common.utils.SecurityUtils;
import cn.ltgodm.template.common.utils.StringUtils;
import cn.ltgodm.template.user.domain.param.ResetPwdParam;
import cn.ltgodm.template.user.domain.param.UserParam;
import cn.ltgodm.template.user.domain.param.UserQueryParam;
import cn.ltgodm.template.user.service.RoleService;
import cn.ltgodm.template.user.service.UserService;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.commons.lang3.ArrayUtils;
import org.springdoc.api.annotations.ParameterObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @author ltgodm
 * @date 2024-03-17 21:33:17
 * 用户管理
 */
@RestController
@RequestMapping("/user")
@Tag(name = "用户管理")
@ApiSupport(author = "ltgodm")
public class UserController {
    @Autowired
    private UserService userService;
    @Autowired
    private RoleService roleService;

    @GetMapping("list")
    @Operation(summary = "分页获取用户信息")
    @PreAuthorize("hasAuthority('system:user:query')")
    public IPage<UserVO> getList(@ParameterObject UserQueryParam userQueryParam) {
        return userService.selectUserList(userQueryParam);
    }
    @GetMapping(value = {"/", "/{userId}"})
    @Operation(summary = "通过id查询用户信息")
    @PreAuthorize("hasAuthority('system:user:query')")
    public AjaxResult getByUserId(@PathVariable(value = "userId", required = false) Long userId) {
        //校验用户权限
        userService.checkUserDataScope(userId);
        AjaxResult ajax = AjaxResult.success();
        List<RoleVO> roles = roleService.selectRoleAll();
        ajax.put("roles", UserVO.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList()));
        if (ObjectUtil.isNotNull(userId)){
            UserVO user = userService.selectUserById(userId);
            ajax.put(AjaxResult.DATA_TAG, user);
            ajax.put("roleIds", user.getRoles().stream().map(RoleVO::getRoleId).collect(Collectors.toList()));
        }
        return ajax;
    }

    @PostMapping
    @Operation(summary = "新增用户信息")
    @PreAuthorize("hasAuthority('system:user:add')")
    @Log(title = "用户管理", businessType = BusinessType.INSERT)
    public AjaxResult add(@Validated @RequestBody UserParam user){
        if (!userService.checkUserNameUnique(user)){

            return AjaxResult.error("新增用户'" + user.getUserName() + "'失败，登录账号已存在");

        }else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user)){

            return AjaxResult.error("新增用户'" + user.getPhonenumber() + "'失败，手机号已存在");

        } else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkEmailUnique(user)) {

            return AjaxResult.error("新增用户'" + user.getEmail() + "'失败，邮箱已存在");

        }

        user.setCreateBy(SecurityUtils.getLoginUser().getUsername());
        user.setPassword(SecurityUtils.encryptPassword(user.getPassword()));
        int row = userService.insertUser(user);
        if (row>0){
            return AjaxResult.success();
        }else {
            return AjaxResult.error();
        }

    }

    @PutMapping
    @Operation(summary = "修改用户信息")
    @PreAuthorize("hasAuthority('system:user:edit')")
    @Log(title = "用户管理", businessType = BusinessType.UPDATE)
    public AjaxResult edit(@Validated @RequestBody UserParam user){

        userService.checkUserAllowed(user);
        if (!userService.checkUserNameUnique(user)){

            return AjaxResult.error("修改用户'" + user.getUserName() + "'失败，登录账号已存在");

        }else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user)){

            return AjaxResult.error("修改用户'" + user.getPhonenumber() + "'失败，手机号已存在");

        } else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkEmailUnique(user)) {

            return AjaxResult.error("修改用户'" + user.getEmail() + "'失败，邮箱已存在");

        }

        user.setUpdateBy(SecurityUtils.getLoginUser().getUsername());
        user.setPassword(SecurityUtils.encryptPassword(user.getPassword()));
        int row = userService.updateUser(user);
        if (row>0){
            return AjaxResult.success();
        }else {
            return AjaxResult.error();
        }

    }

    @DeleteMapping("/{userIds}")
    @Operation(summary = "删除用户")
    @PreAuthorize("hasAuthority('system:user:remove')")
    @Log(title = "用户管理", businessType = BusinessType.DELETE)
    public AjaxResult remove(@PathVariable Long[] userIds)
    {
        if (ArrayUtils.contains(userIds, SecurityUtils.getLoginUser().getUserId()))
        {
            return AjaxResult.error("当前用户不能删除");
        }
        boolean row = userService.deleteUser(userIds);
        if (row){
            return AjaxResult.success();
        }else {
            return AjaxResult.error();
        }
    }

    @PutMapping("resetPwd")
    @Operation(summary = "重置密码")
    @Log(title = "重置密码", businessType = BusinessType.UPDATE)
    @PreAuthorize("hasAuthority('system:user:resetPwd')")
    public AjaxResult resetPassword(@RequestBody UserParam userParam){
        userService.checkUserAllowed(userParam);
        userService.checkUserDataScope(userParam.getUserId());
        int row = userService.resetPwd(userParam);
        if (row >0){
            return AjaxResult.success();
        }else {
            return AjaxResult.error();
        }

    }

    @Operation(summary = "修改用户状态")
    @PutMapping("/changeStatus")
    @PreAuthorize("hasAuthority('system:user:edit')")
    @Log(title = "修改用户状态", businessType = BusinessType.UPDATE)
    public AjaxResult changeStatus(@RequestBody UserParam user)
    {
        userService.checkUserAllowed(user);
        userService.checkUserDataScope(user.getUserId());
        int row = userService.updateUserStatus(user);
        if (row >0){
            return AjaxResult.success();
        }else {
            return AjaxResult.error();
        }
    }
}
